﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace Faml.LinqCompiler
{
    public class ExpressionMetadata<TMetadata>
    {
        private Expression root;
        private Dictionary<Expression, TMetadata> table;


        public ExpressionMetadata(Expression root)
        {
            this.root = root;
            table = new Dictionary<Expression, TMetadata>();
        }

        public TMetadata this[Expression expression]
        {
            get
            {
                return table[expression];
            }
            set
            {
                table[expression] = value;
            }
        }


        public static ExpressionMetadata<TMetadata> BuildForEach(Expression expression, MetadataProvider provider)
        {
            ExpressionMetadata<TMetadata> em = new ExpressionMetadata<TMetadata>(expression);
            ProcessForEach(em, expression, provider);

            return em;
        }

        private static void ProcessForEach(ExpressionMetadata<TMetadata> em, Expression exp, MetadataProvider provider)
        {
            foreach (Expression child in ExpressionUtils.GetChildren(exp))
            {
                ProcessForEach(em, child, provider);
            }

            em.table[exp] = provider(exp, em);
        }


        public delegate TMetadata MetadataProvider(Expression expression, ExpressionMetadata<TMetadata> metadata);
    }
}
